import '@wangeditor/editor/dist/css/style.css'
import React, { useEffect, useState, useRef } from 'react'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import { getGoodById, uploadGoodsEditorImage, createGood, updateGood } from '@/service/goods'
import { Card, Steps, Form, Input, Button, Tabs, Radio, Cascader, message, Checkbox, Image, Upload, Space } from 'antd'
import type { UploadProps, UploadFile } from 'antd'
import { useTranslation } from 'react-i18next'
import { getAllCategories, getCategoryByParams } from '@/service/categories'
import { uploadGoodsImage } from '@/service/goods'
import { RootState, useSelector } from '@/redux'
import type { CheckboxValueType } from 'antd/es/checkbox/Group'
import { UploadOutlined } from '@ant-design/icons'
// 富文本
import { Editor, Toolbar } from '@wangeditor/editor-for-react'
import { IDomEditor, IToolbarConfig } from '@wangeditor/editor'
import { i18nChangeLanguage } from '@wangeditor/editor'

interface Option {
  value: number
  label: string
  children?: Option[]
}
type InsertFnType = (url: string, alt?: string, href?: string) => void
const GoodsAddOrEdit = (props: any) => {
  const { language } = useSelector((state: RootState) => state.global)
  const { t } = useTranslation()
  const navigate = useNavigate()
  const { pathname } = useLocation()
  const [queryParams] = useSearchParams() // 获取query参数
  const [pageType, setPageType] = useState<string>('add')
  const [current, setCurrent] = useState<number>(0)
  const [activeKey, setActiveKey] = useState<string>('0')
  const [categoryList, setCategoryList] = useState<Option[]>([])
  const [manyParamData, setManyParamData] = useState<any>([])
  const [onlyParamData, setOnlyParamData] = useState<any>([])
  const [editor, setEditor] = useState<IDomEditor | null>(null)

  i18nChangeLanguage(language === 'en' ? 'en' : 'zh-CN')
  //工具栏配置
  const toolbarConfig: Partial<IToolbarConfig> = {
    // toolbarKeys: ['headerSelect', 'bold', 'italic'],
    // insertKeys: {}, //自定义扩展菜单
    // excludeKeys: [] //要排除的菜单
  }
  // 编辑器配置
  const editorConfig = {
    autoFocus: true,
    placeholder: '请输入内容...',
    scroll: true,
    MENU_CONF: {}
  } as any

  editorConfig.MENU_CONF['uploadImage'] = {
    // https://img1.doubanio.com/dae/niffler/niffler/images/7bea8578-3f69-11e7-8261-0242ac11001b.png
    async customUpload(file: File, insertFn: InsertFnType) {
      const limit_size = 1024 * 1024 * 1 // 10MB
      if (file.size > limit_size) {
        message.warning('上传文件不能超过1MB!')
        return
      }
      const formdata = new FormData()
      formdata.append('ueditor', file)
      uploadGoodsEditorImage(formdata).then((res: any) => {
        for (let i = 0; i < res.data.length; i++) {
          //插入图片
          insertFn(res.data[i].pic)
        }
      })
    }
  }

  // 及时销毁 editor ，重要！
  useEffect(() => {
    return () => {
      if (editor == null) return
      editor.destroy()
      setEditor(null)
    }
  }, [editor])
  const stepItems = [
    { title: t('goods.step_item.basic_info') },
    { title: t('goods.step_item.goods_params') },
    { title: t('goods.step_item.goods_attrs') },
    { title: t('goods.step_item.goods_pics') },
    { title: t('goods.step_item.goods_content') },
    { title: t('goods.step_item.finish') }
  ]
  const stepStyle: React.CSSProperties = {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 20
  }
  const contentStylle: React.CSSProperties = {
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'flex-start',
    padding: 20
  }
  const formRef = useRef<any>()
  const manyFormRef = useRef<any>()
  const onlyFormRef = useRef<any>()
  const [formValue, setFormValue] = useState<any>({
    goods_name: null,
    goods_price: null,
    goods_weight: null,
    goods_number: null,
    goods_state: 0,
    goods_cat: [], // 商品分类数组
    pics: [],
    goods_introduce: '',
    attrs: [], // 商品的参数数组，包含动态参数和静态属性
    many: [],
    only: []
  })
  const statusList = [
    { label: t('goods.goods_status.un_audit'), value: 0 },
    { label: t('goods.goods_status.auditing'), value: 1 },
    { label: t('goods.goods_status.audited'), value: 2 }
  ]
  // 查询商品分类列表
  const getCateList = () => {
    return new Promise((resolve, reject) => {
      getAllCategories().then((res: any) => {
        setCategoryList(res.data)
        resolve(true)
      })
    })
  }
  // 查询编辑商品详情
  const searchEditDetail = async (id: number) => {
    await getGoodById({ id }).then((res: any) => {
      // 编辑设置值
      const resData = {
        goods_name: res.data.goods_name,
        goods_price: res.data.goods_price,
        goods_weight: res.data.goods_weight,
        goods_number: res.data.goods_number,
        goods_state: res.data.goods_state,
        goods_cat: res.data.goods_cat.split(',').map((i: any) => Number(i)),
        pics: res.data.pics,
        attrs: res.data.attrs.filter((item: any) => {
          return (item.attr_sel = 'amny')
        })
      }
      console.log(resData)
      setFormValue(resData)
      formRef.current.setFieldsValue(resData)
    })
  }
  useEffect(() => {
    getCateList().then(() => {
      if (queryParams.get('id')) {
        searchEditDetail(queryParams.get('id') as any)
        setPageType('edit')
      } else {
        setPageType('add')
      }
    })
  }, [pathname])

  const handleSumit = () => {
    formRef.current?.submit()
  }
  const onFinish = (values: any) => {
    console.log(formValue)
    console.log(manyParamData, 'many')
    console.log(onlyParamData, 'only')
    const form = { ...formValue }
    form.goods_cat = form.goods_cat.join(',')
    manyParamData.forEach((item: any) => {
      form.attrs.push({
        ...item,
        attr_id: item.attr_id,
        attr_vals: item.attr_vals.join(' ')
      })
    })
    onlyParamData.forEach((item: any) => {
      form.attrs.push({
        ...item
      })
    })
    delete form.many
    delete form.only
    console.log(form, '111')

    if (pageType === 'add') {
      createGood(form).then((res: any) => {
        handleSucces()
      })
    } else {
      updateGood({ id: queryParams.get('id'), ...form }).then(() => {
        handleSucces()
      })
    }
  }
  const handleSucces = () => {
    const msg = pageType === 'add' ? '添加商品' : '修改商品'
    message.success(`${msg}成功`)
    navigate('/goods')
  }
  const onFinishFailed = (errInfo: any) => {
    console.log('Failed', errInfo)
  }
  const changeCat = (value: any) => {
    if (value.length !== 3) {
      message.warning('请选择三级商品分类')
      formRef.current.setFieldValue('goods_cat', [])
    } else {
      formRef.current.setFieldValue('goods_cat', value)
    }
  }

  const changeMany = (checkedValues: CheckboxValueType[], id: number) => {
    const checkArr = [] as any
    checkArr.push(...checkedValues)
    const newArr = manyParamData.map((item: any) => {
      const obj = {} as any
      obj.attr_id = item.attr_id
      obj.attr_name = item.attr_name
      obj.cat_id = item.cat_id
      obj.attr_sel = item.attr_sel
      obj.attr_write = item.attr_write
      obj.delete_time = item.delete_time
      obj.attr_vals = item.attr_vals
      if (item.attr_id === id) {
        obj.attr_vals = Array.from(checkArr)
      }
      return obj
    })
    setFormValue({
      ...formValue,
      many: newArr
    })
  }
  // 解决输入中文未完成触发change事件bug
  const [inputId, setInputId] = useState<number>(0)
  const [isOnComposition, setIsOnComposition] = useState<boolean>(true)
  const onCompositionStart = () => {
    setIsOnComposition(true)
  }
  const onCompositionEnd = (e: any) => {
    if (e.type === 'compositionend') {
      setIsOnComposition(false)
      changeContent(e, inputId)
    }
  }
  const changeContent = (e: any, id: any) => {
    setInputId(id)
    if (isOnComposition) {
      const realVal = e.target.value
      const index = onlyParamData.findIndex(function (cur: any, index: number) {
        if (cur.attr_id === id) return index === -1 ? 0 : index - 1
      })
      const newArr = onlyParamData.map((item: any, i: number) => {
        const obj = {} as any
        obj.attr_id = item.attr_id
        obj.attr_name = item.attr_name
        obj.cat_id = item.cat_id
        obj.attr_sel = item.attr_sel
        obj.attr_write = item.attr_write
        obj.delete_time = item.delete_time
        obj.attr_vals = item.attr_vals
        if (i === index) {
          obj.attr_vals = realVal
        }
        return obj
      })
      setOnlyParamData(newArr)
      setFormValue({
        ...formValue,
        only: newArr
      })
    }
  }
  const [fileListArr, setFileListArr] = useState<UploadFile[]>([])
  const uploadProps: UploadProps = {
    onRemove(file) {
      const index = fileListArr.indexOf(file)
      const newFileList = fileListArr.slice()
      newFileList.splice(index, 1)
      setFileListArr(newFileList)
    },
    beforeUpload(file, fileList) {
      return new Promise((resolve, reject) => {
        const limit_type = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif']
        const limit_size = 1024 * 1024 * 2 // 10MB
        if (!limit_type.includes(file.type)) {
          message.warning('上传文件只能是图片类型!')
          setFileListArr([])
          return reject(false)
        }
        if (file.size > limit_size) {
          message.warning('上传文件不能超过2MB!')
          setFileListArr([])
          return reject(false)
        }
        setFileListArr([...fileListArr, ...fileList])
        return resolve(false)
      })
    },
    fileList: fileListArr,
    maxCount: 1,
    multiple: true
  }
  const handleUploadPics = () => {
    const names = fileListArr.map((item: any) => item.name)
    // reduce 去重
    const newNames = names.reduce((pre, cur) => {
      if (!pre.includes(cur)) {
        pre.push(cur)
      }
      return pre
    }, [])
    if (names.length !== newNames.length) {
      message.warning('请勿重复上传文件!')
      return
    }
    const formdata = new FormData()
    for (let i = 0; i < fileListArr.length; i++) {
      formdata.append('fileList', fileListArr[i] as any, fileListArr[i].name)
    }
    uploadGoodsImage(formdata).then((res: any) => {
      setFormValue({
        ...formValue,
        pics: res.data
      })
    })
  }
  const tabItems = [
    {
      key: '0',
      label: t('goods.step_item.basic_info'),
      children: (
        <>
          <Form.Item
            label={t('goods.table.goods_name')}
            name="goods_name"
            rules={[{ required: true, message: t('goods.table.required_name') }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label={t('goods.table.goods_price')}
            name="goods_price"
            rules={[{ required: true, message: t('goods.table.required_price') }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label={t('goods.table.goods_weight')}
            name="goods_weight"
            rules={[{ required: true, message: t('goods.table.required_weight') }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label={t('goods.table.goods_number')}
            name="goods_number"
            rules={[{ required: true, message: t('goods.table.required_number') }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label={t('goods.table.goods_state')}
            name="goods_state"
            rules={[{ required: true, message: t('goods.table.required_state') }]}
          >
            <Radio.Group>
              {statusList.map(item => (
                <Radio key={item.value} value={item.value}>
                  {item.label}
                </Radio>
              ))}
            </Radio.Group>
          </Form.Item>
          <Form.Item
            label={t('goods.table.goods_cat')}
            name="goods_cat"
            rules={[{ required: true, message: t('goods.table.required_cat') }]}
          >
            <Cascader options={categoryList} onChange={changeCat}></Cascader>
          </Form.Item>
        </>
      )
    },
    {
      key: '1',
      label: t('goods.step_item.goods_params'),
      children: (
        <>
          {manyParamData.map((item: any) => (
            <div key={item.attr_id}>
              <span>{item.attr_name}</span>
              <Checkbox.Group
                options={item.attr_vals}
                onChange={(checkedValues: CheckboxValueType[]) => changeMany(checkedValues, item.attr_id)}
                defaultValue={formValue.attrs}
              />
            </div>
          ))}
        </>
      )
    },
    {
      key: '2',
      label: t('goods.step_item.goods_attrs'),
      children: (
        <>
          {onlyParamData.map((item: any) => (
            <div key={item.attr_id}>
              <span>{item.attr_name}</span>
              <Input
                value={item.attr_vals}
                onCompositionEnd={onCompositionEnd}
                onCompositionStart={onCompositionStart}
                onChange={e => changeContent(e, item.attr_id)}
              />
            </div>
          ))}
        </>
      )
    },
    {
      key: '3',
      label: t('goods.step_item.goods_pics'),
      children: (
        <>
          <Space>
            {formValue.pics.length > 0 &&
              formValue.pics.map((item: any) => <Image key={item.pics_id} width={200} src={item.pics_sma}></Image>)}
          </Space>
          <div>
            <Upload {...uploadProps}>
              <Button type="primary">{t('goods.select_file')}</Button>
            </Upload>
            <Button
              type="primary"
              style={{ marginTop: 16 }}
              icon={<UploadOutlined />}
              disabled={fileListArr.length === 0}
              onClick={handleUploadPics}
            >
              {t('goods.start_upload')}
            </Button>
          </div>
        </>
      )
    },
    {
      key: '4',
      label: t('goods.step_item.goods_content'),
      children: (
        <>
          <div style={{ border: '1px solid #ccc', zIndex: 100 }}>
            <Toolbar
              editor={editor}
              defaultConfig={toolbarConfig}
              mode="default"
              style={{ borderBottom: '1px solid #ccc' }}
            />
            <Editor
              defaultConfig={editorConfig}
              value={formValue.goods_introduce}
              onCreated={setEditor}
              onChange={editor => setFormValue({ ...formValue, goods_introduce: editor.getHtml() })}
              mode="default"
              style={{ height: '500px' }}
            />
          </div>
        </>
      )
    },
    {
      key: '5',
      label: t('goods.step_item.finish'),
      children: (
        <Button type="primary" onClick={handleSumit}>
          {t('goods.step_item.finish')}
        </Button>
      )
    }
  ]
  const getParamList = (id: number, sel: string, key: number) => {
    return new Promise((resolve, reject) => {
      getCategoryByParams({ id, sel }).then((res: any) => {
        if (key == 1) {
          setManyParamData(
            res.data.map((item: any) => {
              return {
                ...item,
                attr_vals: item.attr_vals === 0 ? [] : item.attr_vals.split(' ')
              }
            })
          )
        }
        if (key == 2) {
          setOnlyParamData(res.data)
        }
        resolve(true)
      })
    })
  }

  const changeSteps = (key: any) => {
    // 直接调用 formValue.goods_cat 此时获取不到值，建议使用getFieldValue()方法
    if (current === 0 && formRef.current.getFieldValue('goods_cat').length !== 3) {
      message.warning('请先选择商品分类')
      return
    }
    const catId =
      formRef.current.getFieldValue('goods_cat').length === 3 ? formRef.current.getFieldValue('goods_cat')[2] : null
    if (key == 1) {
      getParamList(catId, 'many', key).then(() => {
        console.log('many', manyParamData)
        console.log(formRef.current.getFieldsValue())
        const obj = {} as any
        if (manyParamData.length !== 0) {
          for (let i = 0; i < manyParamData.length; i++) {
            obj[manyParamData[i].attr_name] = manyParamData[i].attr_vals
          }
          console.log('111', obj)
          manyFormRef.current.setFieldsValue(obj)
          console.log(manyFormRef.current.getFieldsValue())
        }
      })
    }
    if (key == 2) {
      getParamList(catId, 'only', key).then(() => {
        console.log('only', onlyParamData)
        console.log(formRef.current.getFieldsValue())
        const obj = {} as any
        if (onlyParamData.length !== 0) {
          for (let i = 0; i < onlyParamData.length; i++) {
            obj[onlyParamData[i].attr_name] = onlyParamData[i].attr_vals
          }
          console.log('111', obj)
          onlyFormRef.current.setFieldsValue(obj)
          console.log(onlyFormRef.current.getFieldsValue())
        }
      })
    }
    setActiveKey(key + '')
    setCurrent(Number(key))
  }
  return (
    <Card>
      <Steps current={current} items={stepItems} onChange={changeSteps} style={stepStyle} />
      <div style={contentStylle}>
        <Form
          name="basic"
          ref={formRef}
          labelAlign="left"
          initialValues={formValue}
          onFinish={onFinish}
          onFinishFailed={onFinishFailed}
        >
          <Tabs items={tabItems} activeKey={activeKey} onChange={changeSteps}></Tabs>
        </Form>
      </div>
    </Card>
  )
}

export default GoodsAddOrEdit
